package com.duke.app.smart.bark;

import java.lang.reflect.Method;
import java.util.ArrayList;

import com.android.internal.telephony.ITelephony;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.TextView;
import android.widget.Toast;
import android.hardware.SensorManager;
import android.hardware.SensorListener;
import android.speech.RecognizerIntent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

import android.hardware.Sensor;

//import com.android.internal.telephony.ITelephony;


public class SmartBark extends Activity /*implements SensorListener*/ implements SensorListener{
    
    TelephonyManager tm;
	SensorManager sm = null;
    int minAnswerDelay;		//Min delay before answering in seconds
    float accelX;
    float orientX;
    
    private int lastPhoneState = 0;
    private long lastUpdate = -1;
    private float x, y, z;
    private float last_x, last_y, last_z;
    private static final int SHAKE_THRESHOLD = 1000;    

    Bundle SIS;
    protected static final int SUB_ACTIVITY_REQUEST_CODE = 100;
	private static final int REQUEST_CODE = 232;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SIS = savedInstanceState;
        minAnswerDelay = 2;
        tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
        sm = (SensorManager) getSystemService(SENSOR_SERVICE);
        lastPhoneState = TelephonyManager.CALL_STATE_IDLE;
//        SpeechActivity SA = new SpeechActivity();
//			SA.onCreate(savedInstanceState);
   
    }
    
	@Override
	public void onAccuracyChanged(int arg0, int arg1) {
		// TODO Auto-generated method stub
	}
    public void onSensorChanged(int sensor, float[] values) {
        synchronized (this) {
            if (sensor == SensorManager.SENSOR_ORIENTATION) {     	
            	orientX = values[0];
            }
            if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
            	accelX = values[0];
            	
        	    long curTime = System.currentTimeMillis();
        	    // only allow one update every 100ms.
        	    if ((curTime - lastUpdate) > 100) {
        		long diffTime = (curTime - lastUpdate);
        		lastUpdate = curTime;
         
        		x = values[SensorManager.DATA_X];
        		y = values[SensorManager.DATA_Y];
        		z = values[SensorManager.DATA_Z];
         
        		float speedx = Math.abs(x+y - last_x - last_y) / diffTime * 10000;
        		float speedz = Math.abs(y+z - last_y - last_z) / diffTime * 10000;
        		if (speedz > SHAKE_THRESHOLD) {
        	        Toast.makeText(SmartBark.this, "Shaken Z-direction", Toast.LENGTH_SHORT).show();
        			if(lastPhoneState == TelephonyManager.CALL_STATE_RINGING) {
        		        Toast.makeText(SmartBark.this, "Shaken and ringing", Toast.LENGTH_SHORT).show();
        	            answerPhone(true);
        			}
        		}
        		if (speedx > SHAKE_THRESHOLD) {
        	        Toast.makeText(SmartBark.this, "Shaken X-direction", Toast.LENGTH_SHORT).show();
        			if(lastPhoneState == TelephonyManager.CALL_STATE_RINGING) {
        		        Toast.makeText(SmartBark.this, "Shaken and ringing", Toast.LENGTH_SHORT).show();
        	            answerPhone(false);
        			}
        		}
        		last_x = x;
        		last_y = y;
        		last_z = z;
        	    }
        	}
        }
    }
	@Override
    protected void onResume() {
        super.onResume();
        sm.registerListener(this, 
                SensorManager.SENSOR_ORIENTATION |
        		SensorManager.SENSOR_ACCELEROMETER,
                SensorManager.SENSOR_DELAY_NORMAL);
    }
    @Override
    protected void onStop() {
        sm.unregisterListener(this);
        super.onStop();
    }
    
    private void startVoiceRecognitionActivity2()
    {
        Toast.makeText(SmartBark.this, "Starting Speech Recognition", Toast.LENGTH_SHORT).show();

        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        startActivityForResult(intent, REQUEST_CODE);
    }
    
    /*@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(requestCode == SUB_ACTIVITY_REQUEST_CODE){
			Bundle b = data.getExtras();
   	     	Toast.makeText(SmartBark.this, b.getString("TEXT") + " ,DONE", Toast.LENGTH_SHORT).show();
        }
	}*/
    
    /**
     * Handle the results from the voice recognition activity.
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK)
        {
            // Populate the wordsList with the String values the recognition engine thought it heard
            ArrayList<String> matches = data.getStringArrayListExtra(
                    RecognizerIntent.EXTRA_RESULTS);
            ArrayList<String> temp = new ArrayList<String>();
            temp.add(matches.get(0));
            Toast.makeText(SmartBark.this, matches.get(0), Toast.LENGTH_SHORT).show();

            setResult(resultCode, data);
        }
        //super.onActivityResult(requestCode, resultCode, data);
    }
    
    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
    	  public void onCallStateChanged(int state, String incomingNumber) {
    		  lastPhoneState = state;
    	   try {
    	    switch (state) {
    	    case TelephonyManager.CALL_STATE_RINGING:
    	     Toast.makeText(SmartBark.this, "CALL_STATE_RINGING", Toast.LENGTH_SHORT).show();
    	     
     	         Toast.makeText(SmartBark.this, "ringing accelx: " + accelX, Toast.LENGTH_SHORT).show();
 			 
 			 /*Toast.makeText(SmartBark.this, "Orientation X: " + orientX, Toast.LENGTH_SHORT).show();
 			 Toast.makeText(SmartBark.this, "Accel X: " + accelX, Toast.LENGTH_SHORT).show();*/

             //New intent code here:
             /*Intent intent = new Intent(SmartBark.this, SpeechActivity.class);
			 startActivityForResult(intent, SUB_ACTIVITY_REQUEST_CODE);*/
			 
 			 /*startVoiceRecognitionActivity2();	//This is the correct one*/

             //SpeechActivity activity = new SpeechActivity();
             
//             SpeechActivity SA = new SpeechActivity();
//             SA.onCreate(SIS);
 			             
    		 // Answer the phone
 			 //if(activity.isDoneConverting() && (activity.getConvertedString().equals("answer") || activity.getConvertedString().equals("Answer"))) {//
					/*try {
							answerPhoneAidl(context);
					} catch (Exception e) {
							e.printStackTrace();
							Log.d("AutoAnswer",
									"Error trying to answer using telephony service.  Falling back to headset.");
							answerPhoneHeadsethook(context);
					}
					enableSpeakerPhone(context);*/
 			 //}

    	     break;
    	    case TelephonyManager.CALL_STATE_OFFHOOK:
    	     Toast.makeText(SmartBark.this, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT).show();
 	         Toast.makeText(SmartBark.this, "offhook accelx: " + accelX, Toast.LENGTH_SHORT).show();

//    	     Intent i1 = new Intent(SmartBark.this,
//  					SpeechActivity.class);
//    	     //startVoiceRecognitionActivity();
//  			startActivityForResult(i1, SUB_ACTIVITY_REQUEST_CODE);
    	     break;
    	    case TelephonyManager.CALL_STATE_IDLE:
    	     Toast.makeText(SmartBark.this, "CALL_STATE_IDLE", Toast.LENGTH_SHORT).show();
    	     break;
    	    default:
    	     Toast.makeText(SmartBark.this, "default", Toast.LENGTH_SHORT).show();
    	     Log.i("Default", "Unknown phone state=" + state);
    	    }
    	   } catch (Exception e) {
    	    Log.i("Exception", "PhoneStateListener() e = " + e);
    	   }
    	  }
    	 };
    	 
    	 private void answerPhone(boolean withSpeaker) {
	            Context context = getBaseContext();
				try {
					answerPhoneAidl(context);
				} catch (Exception e) {
					e.printStackTrace();
					Log.d("AutoAnswer",
							"Error trying to answer using telephony service.  Falling back to headset.");
					answerPhoneHeadsethook(context);
				}
				if(withSpeaker)
    				enableSpeakerPhone(context);
    	 }
    
    		private void answerPhoneHeadsethook(Context context) {
    			// Simulate a press of the headset button to pick up the call
    			Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);		
    			buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
    			context.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED");

    			// froyo and beyond trigger on buttonUp instead of buttonDown
    			Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);		
    			buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
    			context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
    		}

    		@SuppressWarnings("unchecked")
    		private void answerPhoneAidl(Context context) throws Exception {
    			// Set up communication with the telephony service (thanks to Tedd's Droid Tools!)
    			TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    			Class c = Class.forName(tm.getClass().getName());
    			Method m = c.getDeclaredMethod("getITelephony");
    			m.setAccessible(true);
    			ITelephony telephonyService;
    			telephonyService = (ITelephony)m.invoke(tm);

    			// Silence the ringer and answer the call!
    			telephonyService.silenceRinger();
    			telephonyService.answerRingingCall();
    		}
    		
    		private void enableSpeakerPhone(Context context) {
                AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
                audioManager.setSpeakerphoneOn(true);
    		}

}